﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpDatabase.h"
#include "GbmpQuickCast.h"
#include "GbmpTypeDefs.h"
#include "GcmpApiDeclaration.h"


namespace gcmp
{
    class NdbClassSchema;
    class IDbObject;
    /// \brief Ndb数据对象基类
    ///
    /// 不需要直接继承，通过继承NdbObjectSchematic、NdbObjectCloneable、NdbElement等它的派生类来使用。
    class GCMP_DATABASE_EXPORT NdbObject
    {
        DEFINE_CAST_BASE(gcmp::NdbObject)

    public:
#pragma region 需要具体派生类数据对象实现的方法
        /// \brief 获取该NdbObject的最顶层所有者
        ///
        /// 顶层所有者通常是Element。
        ///
        /// \return NdbObject * 顶层所有者指针
        /// \note 如果该NdbObject作为Element的成员，派生类一定要实现该方法，返回正确指针，否则数据发生变化时框架无法通知Element。
        virtual NdbObject* GetTopOwnerObject() const = 0;
#pragma endregion

    public:
        /// \brief  获取类schema的指针
        /// \return const NdbClassSchema * 获取的类schema指针。派生类提供了覆盖实现。
        virtual const NdbClassSchema * GetClassSchema() const { return nullptr; }

        /// \brief  检测是否是单继承以及检测宏DBOBJECT_DATA_BEGIN在多继承时是否使用了第一个父类的名字
        ///
        /// 满足从某个父类单继承过来；或者多继承，但除第一个父类外其余父类没有成员。派生类提供了覆盖实现。
        /// 多继承时，如果在宏DBOBJECT_DATA_BEGIN中使用了第一个父类的名字，也是返回true
        ///
        /// \return bool 满足单继承条件或是多继承的条件
        virtual bool CheckClassInheritanceRelationship() const { return false; }

        /// \brief  是否是一个完整的对象
        ///
        /// 完整对象用对应的NdbObject表示；否则使用一个平台内部特定对象来表达。 非完整对象的GetSerializationData()才有意义。
        /// 对象的部分数据不完整，还用对应的NdbObject表示，但此字段返回false。
        ///
        /// \return bool 是-true；否-false
        /// \see GetSerializationData()
        virtual bool IsComplete() const { return true; }

        /// \brief  设置是否是一个完整的对象
        /// \param  isComplete 是否是完整的
        virtual void SetIsComplete(bool isComplete) {}

        /// \brief  获取非完整对象的二进制序列化数据
        ///
        /// 非完整的对象才有二进制序列化数据。
        ///
        /// \param[out] bytes 获取到的序列化数据。传入值首先被清空。平台内部特定对象提供了覆盖实现。
        /// \return bool 非完整对象返回true
        /// \see IsComplete()
        virtual bool GetContaineeData(std::vector<Byte> & bytes) const { return false; }

        virtual void CheckTopOwnerObject(std::vector<const UniqueWString*>& path,const NdbObject* correctowner,
            const NdbClassSchema* pNdbClassSchema, std::vector<std::wstring>& resultstr) const;

        /// \brief 构造函数
        explicit NdbObject(void);

        /// \brief 析构函数
        virtual ~NdbObject(void) = 0;      
    }; 
}
